<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Language Extensions
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora210.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora212.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Language Extensions</H2>Objective CAML 3.04 brings three language extensions to Objective CAML: labels,
optional arguments, and polymorphic constructors. These extensions
preserve backward compatibility with the original language: a program
written for version 2.04 keeps the same semantics in version 3.04.<BR>
<BR>
<A NAME="toc318"></A>
<H3> Labels</H3>
<A NAME="@concepts363"></A>
<A NAME="@fonctions494"></A>
<A NAME="@fonctions495"></A>A <A NAME="label"></A> label is an annotation for the arguments of a function
in its declaration and its application. It is presented as a separate
identifier of the function parameter (formal or actual), enclosed
between an initial symbol <CODE>'</CODE><TT>~</TT><CODE>'</CODE>
and a final symbol <CODE>'</CODE><B>:</B><CODE>'</CODE>.<BR>
<BR>
Labels can appear in the declarations of functions:


<H3> Syntax </H3> <HR>


<B>let</B> <I>f</I> <TT>~</TT><I>label</I>:<I>p</I> <B>=</B>
<I>exp</I>



<HR>


in the anonymous declarations with the keyword <B>fun</B> :


<H3> Syntax </H3> <HR>


<B>fun</B> <TT>~</TT><I>label</I>:<I>p</I> <B>-&gt;</B> <I>exp</I>



<HR>


and in the actual parameter of a function:


<H3> Syntax </H3> <HR>


<B>(</B> <I>f</I>  <TT>~</TT><I>label</I>:<I>exp</I> <B>)</B>



<HR>

<BR>
<BR>

<H5> Labels in types</H5>
The labels given to arguments of a functional expression appear in its
type and annotate the types of the arguments to which they refer.
(The <CODE>'</CODE><TT>~</TT><CODE>'</CODE> symbol in front of the label is omitted in
types.)


<PRE><BR># <B>let</B><CODE> </CODE>add<CODE> </CODE><CODE>~</CODE>op1<CODE>:</CODE>x<CODE> </CODE><CODE>~</CODE>op2<CODE>:</CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>val add : op1:int -&gt; op2:int -&gt; int = &lt;fun&gt;</CODE><BR><BR># <B>let</B><CODE> </CODE>mk_triplet<CODE> </CODE><CODE>~</CODE>arg1<CODE>:</CODE>x<CODE> </CODE><CODE>~</CODE>arg2<CODE>:</CODE>y<CODE> </CODE><CODE>~</CODE>arg3<CODE>:</CODE>z<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>x<CODE>,</CODE>y<CODE>,</CODE>z<TT>)</TT><CODE> </CODE>;;<BR><CODE>val mk_triplet : arg1:'a -&gt; arg2:'b -&gt; arg3:'c -&gt; 'a * 'b * 'c = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
If one wishes to give the same identifier to the label and the
variable, as in <CODE>~x:x</CODE>, it is unnecessary to repeat the identifier;
the shorter syntax <CODE>~x</CODE> can be used instead.<BR>
<BR>


<H3> Syntax </H3> <HR>


 <B>fun</B> <I><TT>~</TT></I><I>p</I>  -&gt; exp



<HR>




<PRE><BR># <B>let</B><CODE> </CODE>mk_triplet<CODE> </CODE><CODE>~</CODE>arg1<CODE> </CODE><CODE>~</CODE>arg2<CODE> </CODE><CODE>~</CODE>arg3<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>arg1<CODE>,</CODE>arg2<CODE>,</CODE>arg3<TT>)</TT><CODE> </CODE>;;<BR><CODE>val mk_triplet : arg1:'a -&gt; arg2:'b -&gt; arg3:'c -&gt; 'a * 'b * 'c = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
It is not possible to define labels in a declaration of a function by
pattern matching; consequently the keyword <B>function</B> cannot be
used for a function with a label.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>~</CODE>arg<CODE>:</CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>Toplevel input:</CODE><BR><CODE># </CODE><BR><CODE>  let f = function </CODE><CODE>~</CODE><CODE>arg:x -&gt; x ;;</CODE><BR><CODE>                   ^^^^^</CODE><BR><CODE>Syntax error</CODE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>fun</B><CODE> </CODE><CODE>~</CODE>arg<CODE>:</CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val f : arg:'a -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Labels in function applications</H5>
When a function is defined with labeled parameters, applications of
this function require that matching labels are provided on the
function arguments.


<PRE><BR># mk_triplet<CODE> </CODE><CODE>~</CODE>arg1<CODE>:</CODE><CODE>'1'</CODE><CODE> </CODE><CODE>~</CODE>arg2<CODE>:</CODE><CODE>2</CODE><CODE> </CODE><CODE>~</CODE>arg3<CODE>:</CODE><CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : char * int * float = '1', 2, 3</CODE><BR># mk_triplet<CODE> </CODE><CODE>'1'</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : char * int * float = '1', 2, 3</CODE><BR>

</PRE>
<BR>
<BR>
A consequence of this requirement is that the order of arguments
having a label does not matter, since one can identify them by their
label. Thus, labeled arguments to a function can be ``commuted'',
that is, passed in an order different from the function definition.<BR>
<BR>


<PRE><BR># mk_triplet<CODE> </CODE><CODE>~</CODE>arg2<CODE>:</CODE><CODE>2</CODE><CODE> </CODE><CODE> </CODE><CODE>~</CODE>arg1<CODE>:</CODE><CODE>'1'</CODE><CODE> </CODE><CODE> </CODE><CODE>~</CODE>arg3<CODE>:</CODE><CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : char * int * float = '1', 2, 3</CODE><BR>

</PRE>
<BR>
<BR>
This feature is particularly useful for making a partial application
on an argument that is not the first in the declaration.


<PRE><BR># <B>let</B><CODE> </CODE>triplet_0_0<CODE> </CODE><CODE>=</CODE><CODE> </CODE>mk_triplet<CODE> </CODE><CODE>~</CODE>arg2<CODE>:</CODE><CODE>0</CODE><CODE> </CODE><CODE>~</CODE>arg3<CODE>:</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val triplet_0_0 : arg1:'a -&gt; 'a * int * int = &lt;fun&gt;</CODE><BR># triplet_0_0<CODE> </CODE><CODE>~</CODE>arg1<CODE>:</CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : int * int * int = 2, 0, 0</CODE><BR>

</PRE>
<BR>
<BR>
Arguments that have no label, or that have the same label as another
argument, do not commute. In such a case, the application uses
the first argument that has the given label.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>test<CODE> </CODE><CODE>~</CODE>arg1<CODE>:_</CODE><CODE> </CODE><CODE>~</CODE>arg2<CODE>:_</CODE><CODE> </CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE> </CODE><CODE>~</CODE>arg2<CODE>:_</CODE><CODE> </CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val test : arg1:'a -&gt; arg2:'b -&gt; 'c -&gt; arg2:'d -&gt; 'e -&gt; unit = &lt;fun&gt;</CODE><BR><BR># test<CODE> </CODE><CODE>~</CODE>arg2<CODE>:</CODE>()<CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE>(* the first arg2: in the declaration *)</CODE><BR><CODE>- : arg1:'a -&gt; 'b -&gt; arg2:'c -&gt; 'd -&gt; unit = &lt;fun&gt;</CODE><BR><BR># test<CODE> </CODE>()<CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* the first unlabeled argument in the declaration *)</CODE><BR><CODE>- : arg1:'a -&gt; arg2:'b -&gt; arg2:'c -&gt; 'd -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Legibility of code</H5>
Besides allowing re-ordering of function arguments, labels are also
very useful to make the function interface more explicit. Consider
for instance the <TT>String.sub</TT> standard library function.


<PRE><BR># String.sub<CODE> </CODE>;;<BR><CODE>- : string -&gt; int -&gt; int -&gt; string = &lt;fun&gt;</CODE><BR>

</PRE>

In the type of this function, nothing indicates that the first
integer argument is a character position, while the second is the
length of the string to be extracted. Objective CAML 3.04 provides
a ``labelized'' version of this function, where the purpose of the
different function arguments have been made explicit using labels.


<PRE><BR># StringLabels.sub<CODE> </CODE>;;<BR><CODE>- : string -&gt; pos:int -&gt; len:int -&gt; string = &lt;fun&gt;</CODE><BR>

</PRE>

Clearly, the function <TT>StringLabels.sub</TT> takes as arguments a
string, the position of the first character, and the length of the
string to be extracted.<BR>
<BR>
Objective CAML 3.04 provides ``labelized'' versions of many standard library
functions in the modules <TT>ArrayLabels</TT>,
<TT>ListLabels</TT>, <TT>StringLabels</TT>, <TT>UnixLabels</TT>, and
<TT>MoreLabels</TT>.
Table <A HREF="book-ora211.html#fig-label-conv">B.1</A> gives the labeling conventions that were
used.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>label</TD>
<TD  ALIGN=left NOWRAP>significance</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>pos:</TD>
<TD  ALIGN=left NOWRAP>a position in a string or array</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>len:</TD>
<TD  ALIGN=left NOWRAP>a length</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>buf:</TD>
<TD  ALIGN=left NOWRAP>a string used as buffer</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>src:</TD>
<TD  ALIGN=left NOWRAP>the source of an operation</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>dst:</TD>
<TD  ALIGN=left NOWRAP>the destination of an operation</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>init:</TD>
<TD  ALIGN=left NOWRAP>the initial value for an iterator</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>cmp:</TD>
<TD  ALIGN=left NOWRAP>a comparison function</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>mode:</TD>
<TD  ALIGN=left NOWRAP>an operation mode or a flag list</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure B.1: Conventions for labels</DIV><BR>

<A NAME="fig-label-conv"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE><A NAME="toc319"></A>
<H3> Optional arguments</H3>
<A NAME="@concepts364"></A>
<A NAME="@fonctions496"></A>Objective CAML 3.04 allows the definition of functions with labeled
optional arguments. Such arguments are defined with a default
value (the value given to the parameter if the application does not
give any other explicitly).<BR>
<BR>


<H3> Syntax </H3> <HR>


 <B>fun</B> <B>?</B><I>name</I>: <B>(</B> <I>p</I> <B>=</B>
 <I>exp</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB><B>)</B>  -&gt; exp<SUB><FONT SIZE=2>2</FONT></SUB> 



<HR>

<BR>
<BR>
As in the case of regular labels, the argument label can be omitted if
it is identical to the argument identifier:<BR>
<BR>


<H3> Syntax </H3> <HR>


 <B>fun</B> <B>?</B><B>(</B> <I>name</I> <B>=</B>
 <I>exp</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB><B>)</B>  -&gt; exp<SUB><FONT SIZE=2>2</FONT></SUB> 



<HR>

<BR>
<BR>
Optional arguments appear in the function type prefixed with the
<B>?</B> symbol.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>sp_incr<CODE> </CODE><CODE>?</CODE>inc<CODE>:</CODE><TT>(</TT>x<CODE>=</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>y<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>!</CODE>y<CODE> </CODE><CODE>+</CODE><CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val sp_incr : ?inc:int -&gt; int ref -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

The function <TT>sp_incr</TT> behaves like the function <TT>incr</TT>
from the Pervasives module.


<PRE><BR># <B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE>sp_incr<CODE> </CODE>v<CODE> </CODE>;<CODE> </CODE>v<CODE> </CODE>;;<CODE> </CODE><BR><CODE>- : int ref = {contents = 5}</CODE><BR>

</PRE>

However, one can specify a different increment from the default.


<PRE><BR># <B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE>sp_incr<CODE> </CODE><CODE>~</CODE>inc<CODE>:</CODE><CODE>3</CODE><CODE> </CODE>v<CODE> </CODE>;<CODE> </CODE>v<CODE> </CODE>;;<BR><CODE>- : int ref = {contents = 7}</CODE><BR>

</PRE>
<BR>
<BR>
A function is applied by giving the default value to all the optional
parameters until the actual parameter is passed by the application. If
the argument of the call is given without a label, it is considered as
being the first non-optional argument of the function.


<PRE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE><CODE>?</CODE><TT>(</TT>x1<CODE>=</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>?</CODE><TT>(</TT>x2<CODE>=</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>x3<CODE> </CODE>x4<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>*</CODE>x1<CODE>+</CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>*</CODE>x2<CODE>+</CODE><CODE>1</CODE><CODE>0</CODE><CODE>*</CODE>x3<CODE>+</CODE>x4<CODE> </CODE>;;<BR><CODE>val f : ?x1:int -&gt; ?x2:int -&gt; int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># f<CODE> </CODE><CODE>3</CODE><CODE> </CODE>;;<BR><CODE>- : int -&gt; int = &lt;fun&gt;</CODE><BR># f<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : int = 34</CODE><BR># f<CODE> </CODE><CODE>~</CODE>x1<CODE>:</CODE><CODE>1</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : int = 1034</CODE><BR># f<CODE> </CODE><CODE>~</CODE>x2<CODE>:</CODE><CODE>2</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : int = 234</CODE><BR>

</PRE>
<BR>
<BR>
An optional argument can be given without a default value, in this
case it is considered in the body of the function as being of the type
<I>'a option</I>; <TT>None</TT> is its default value.


<H3> Syntax </H3> <HR>


 <B>fun</B> <B>?</B><I>name</I><I>:</I><I>p</I>  -&gt; exp 



<HR>

<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>print_integer<CODE> </CODE><CODE>?</CODE>file<CODE>:</CODE>opt_f<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE>opt_f<CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>None<CODE> </CODE>-&gt;<CODE> </CODE>print_int<CODE> </CODE>n<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Some<CODE> </CODE>f<CODE> </CODE>-&gt;<CODE> </CODE><B>let</B><CODE> </CODE>fic<CODE> </CODE><CODE>=</CODE><CODE> </CODE>open_out<CODE> </CODE>f<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>fic<CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>n<TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>fic<CODE> </CODE><CODE>"\n"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>close_out<CODE> </CODE>fic<CODE> </CODE>;;<BR><CODE>val print_integer : ?file:string -&gt; int -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

By default, the function <TT>print_integer</TT> displays its argument
on standard output. If it receives a file name with the label
<TT>file</TT>, it outputs its integer argument to that file instead.<BR>
<BR>


<H3> Note </H3> <HR>


If the last parameter of a function is optional, it will have to be
applied explicitly.



<HR>




<PRE><BR># <B>let</B><CODE> </CODE>test<CODE> </CODE><CODE>?</CODE>x<CODE> </CODE><CODE>?</CODE>y<CODE> </CODE><CODE> </CODE>n<CODE> </CODE><CODE> </CODE><CODE>?</CODE>a<CODE> </CODE><CODE>?</CODE>b<CODE> </CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE>n<CODE> </CODE>;;<BR><CODE>val test : ?x:'a -&gt; ?y:'b -&gt; 'c -&gt; ?a:'d -&gt; ?b:'e -&gt; 'c = &lt;fun&gt;</CODE><BR># test<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : ?a:'_a -&gt; ?b:'_b -&gt; int = &lt;fun&gt;</CODE><BR># test<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>~</CODE>b<CODE>:</CODE><CODE>'x'</CODE><CODE> </CODE>;;<BR><CODE>- : ?a:'_a -&gt; int = &lt;fun&gt;</CODE><BR># test<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>~</CODE>a<CODE>:</CODE>()<CODE> </CODE><CODE>~</CODE>b<CODE>:</CODE><CODE>'x'</CODE><CODE> </CODE>;;<BR><CODE>- : int = 1</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc320"></A>
<H3> Labels and objects</H3> Labels can be used for the parameters of a method or an object's
constructor.<BR>
<BR>


<PRE><BR># <B>class</B><CODE> </CODE>point<CODE> </CODE><CODE>?</CODE><TT>(</TT>x<CODE>=</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>?</CODE><TT>(</TT>y<CODE>=</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><TT>(</TT>col<CODE> </CODE><CODE>:</CODE><CODE> </CODE>Graphics.color<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>object</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>pos<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>x<CODE>,</CODE>y<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE>color<CODE> </CODE><CODE>=</CODE><CODE> </CODE>col<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>print<CODE> </CODE><CODE>?</CODE>dest<CODE>:</CODE><TT>(</TT>file<CODE>=</CODE>stdout<TT>)</TT><CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>file<CODE> </CODE><CODE>"point ("</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>file<CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE><TT>(</TT>fst<CODE> </CODE>pos<TT>)</TT><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>file<CODE> </CODE><CODE>","</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>file<CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE><TT>(</TT>snd<CODE> </CODE>pos<TT>)</TT><TT>)</TT><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_string<CODE> </CODE>file<CODE> </CODE><CODE>")\n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>class point :</CODE><BR><CODE>  ?x:int -&gt;</CODE><BR><CODE>  ?y:int -&gt;</CODE><BR><CODE>  Graphics.color -&gt;</CODE><BR><CODE>  object</CODE><BR><CODE>    method print : ?dest:out_channel -&gt; unit -&gt; unit</CODE><BR><CODE>    val color : Graphics.color</CODE><BR><CODE>    val pos : int * int</CODE><BR><CODE>  end</CODE><BR><BR># <B>let</B><CODE> </CODE>obj1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>point<CODE> </CODE><CODE>~</CODE>x<CODE>:</CODE><CODE>1</CODE><CODE> </CODE><CODE>~</CODE>y<CODE>:</CODE><CODE>2</CODE><CODE> </CODE>Graphics.white<CODE> </CODE><BR><CODE> </CODE><B>in</B><CODE> </CODE>obj1#print<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>point (1,2)</CODE><BR><CODE>- : unit = ()</CODE><BR># <B>let</B><CODE> </CODE>obj2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>point<CODE> </CODE>Graphics.black<CODE> </CODE><BR><CODE> </CODE><B>in</B><CODE> </CODE>obj2#print<CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>point (0,0)</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
Labels and optional arguments provide an alternative to method
and constructor overloading often found in object-oriented
languages, but missing from Objective CAML.<BR>
<BR>
This emulation of overloading has some limitations. In particular, 
it is necessary that at least one of the arguments is not optional.
A dummy argument of type <I>unit</I> can always be used.<BR>
<BR>


<PRE><BR># <B>class</B><CODE> </CODE>number<CODE> </CODE><CODE>?</CODE>integer<CODE> </CODE><CODE>?</CODE>real<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>object</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>val</B><CODE> </CODE><B>mutable</B><CODE> </CODE>value<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>method</B><CODE> </CODE>print<CODE> </CODE><CODE>=</CODE><CODE> </CODE>print_float<CODE> </CODE>value<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>initializer</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>match</B><CODE> </CODE><TT>(</TT>integer<CODE>,</CODE>real<TT>)</TT><CODE> </CODE><B>with</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>None<CODE>,</CODE>None<TT>)</TT><CODE> </CODE><CODE>|</CODE><CODE> </CODE><TT>(</TT>Some<CODE> </CODE><CODE>_,</CODE>Some<CODE> </CODE><CODE>_</CODE><TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>failwith<CODE> </CODE><CODE>"incorrect number"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><TT>(</TT>None<CODE>,</CODE>Some<CODE> </CODE>f<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>value<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>f<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><TT>(</TT>Some<CODE> </CODE>n<CODE>,</CODE>None<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE>value<CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>float_of_int<CODE> </CODE>n<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><CODE> </CODE>;;<BR><CODE>class number :</CODE><BR><CODE>  ?integer:int -&gt;</CODE><BR><CODE>  ?real:float -&gt;</CODE><BR><CODE>  unit -&gt; object method print : unit val mutable value : float end</CODE><BR><BR># <B>let</B><CODE> </CODE>n1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>number<CODE> </CODE><CODE>~</CODE>integer<CODE>:</CODE><CODE>1</CODE><CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val n1 : number = &lt;obj&gt;</CODE><BR># <B>let</B><CODE> </CODE>n2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>new</B><CODE> </CODE>number<CODE> </CODE><CODE>~</CODE>real<CODE>:</CODE><CODE>1</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>()<CODE> </CODE>;;<BR><CODE>val n2 : number = &lt;obj&gt;</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc321"></A>
<H3> Polymorphic variants</H3>
<A NAME="@concepts365"></A>
<A NAME="@fonctions497"></A>The variant types of Objective CAML have two principal limitations. First,
it is not possible to extend a variant type with a new
constructor. Also, a constructor can belong to only one
type. Objective CAML 3.04 features an alternate kind of variant types, called
polymorphic variants that do not have these two
constraints.<BR>
<BR>
Constructors for polymorphic variants are prefixed with a <B>`</B>
(backquote) character, to distinguish them from regular constructors.
Apart from this, the syntactic constraints on polymorphic constructors
are the same as for other constructors. In particular, the identifier
used to build the constructor must begin with a capital letter.<BR>
<BR>


<H3> Syntax </H3> <HR>


 <B>`</B><I>Name</I>



<HR>


ou


<H3> Syntax </H3> <HR>


 <B>`</B><I>Name</I> <I>type</I>



<HR>

<BR>
<BR>
A group of polymorphic variant constructors forms a type, but this
type does not need to be declared before using the constructors.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>`</CODE>Integer<CODE> </CODE><CODE>3</CODE><CODE> </CODE>;;<BR><CODE>val x : [&gt; `Integer of int] = `Integer 3</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="@fonctions498"></A>
<A NAME="@fonctions499"></A>
The type of <TT>x</TT> with the symbol <B>[&gt;</B> indicates that the
type contains at least the constructor <TT>`Integer</TT>
<I>int</I>.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>int_of<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>`</CODE>Integer<CODE> </CODE>n<CODE> </CODE>-&gt;<CODE> </CODE>n<CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>`</CODE>Real<CODE> </CODE>r<CODE> </CODE>-&gt;<CODE> </CODE>int_of_float<CODE> </CODE>r<CODE> </CODE>;;<BR><CODE>val int_of : [&lt; `Integer of int | `Real of float] -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Conversely, the symbol <B>[&lt;</B> indicates that the argument of
<TT>int_of</TT> belongs to the type that contains at most the
constructors <TT>`Integer</TT> <I>int</I> and <TT>`Real</TT>
<I>float</I>.<BR>
<BR>
It is also possible to define a polymorphic variant type by
enumerating its constructors:
 

<H3> Syntax </H3> <HR>


 <B>type</B> <I>t</I> <B>=</B> <B>[</B> <B>`</B><I>Name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB>
 <B>|</B> <B>`</B><I>Name</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> <B>|</B> ... <B>|</B>
 <B>`</B><I>Name</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>]</B> 



<HR>


or for parameterized types:


<H3> Syntax </H3> <HR>
  <B>type</B> <I>('a,'b,...)</I> <I>t</I>
 <B>=</B> <B>[</B> <B>`</B><I>Name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>|</B>
 <B>`</B><I>Name</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> <B>|</B> ... <B>|</B>
 <B>`</B><I>Name</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>]</B> 


<HR>

<BR>
<BR>


<PRE><BR># <B>type</B><CODE> </CODE>value<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>`</CODE>Integer<CODE> </CODE><B>of</B><CODE> </CODE>int<CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>`</CODE>Real<CODE> </CODE><B>of</B><CODE> </CODE>float<CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>type value = [ `Integer of int | `Real of float]</CODE><BR>

</PRE>
<BR>
<BR>
Constructors of polymorphic variants can take arguments of different types.


<PRE><BR># <B>let</B><CODE> </CODE>v1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>`</CODE>Number<CODE> </CODE><CODE>2</CODE><CODE> </CODE><BR><CODE> </CODE><B>and</B><CODE> </CODE>v2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>`</CODE>Number<CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val v1 : [&gt; `Number of int] = `Number 2</CODE><BR><CODE>val v2 : [&gt; `Number of float] = `Number 2</CODE><BR>

</PRE>

However, <TT>v1</TT> and <TT>v2</TT> have different types.


<PRE><BR># v1<CODE>=</CODE>v2<CODE> </CODE>;;<BR><CODE>Toplevel input:</CODE><BR><CODE># </CODE><BR><CODE>  v1=v2 ;;</CODE><BR><CODE>     ^^</CODE><BR><CODE>This expression has type [&gt; `Number of float] but is here used with type</CODE><BR><CODE>  [&gt; `Number of int]</CODE><BR>

</PRE>
<BR>
<BR>
More generally, the constraints on the type of arguments for
polymorphic variant constructors are accumulated in their type by the
annotation <B>&amp;</B>.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>test_nul_integer<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>`</CODE>Number<CODE> </CODE>n<CODE> </CODE>-&gt;<CODE> </CODE>n<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><BR><CODE> </CODE><B>and</B><CODE> </CODE>test_nul_real<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>`</CODE>Number<CODE> </CODE>r<CODE> </CODE>-&gt;<CODE> </CODE>r<CODE>=</CODE><CODE>0</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val test_nul_integer : [&lt; `Number of int] -&gt; bool = &lt;fun&gt;</CODE><BR><CODE>val test_nul_real : [&lt; `Number of float] -&gt; bool = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>test_nul<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>test_nul_integer<CODE> </CODE>x<TT>)</TT><CODE> </CODE><CODE>||</CODE><CODE> </CODE><TT>(</TT>test_nul_real<CODE> </CODE>x<TT>)</TT><CODE> </CODE>;;<BR><CODE>val test_nul : [&lt; `Number of float &amp; int] -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>

The type of <TT>test_nul</TT> indicates that the only values accepted
by this function are those with the constructor <TT>`Number</TT> and
an argument which is at the same time of type <I>int</I> and of
<I>float</I>. That is, the only acceptable values are of type <I>'a</I>!


<PRE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE>test_nul<CODE> </CODE><TT>(</TT>failwith<CODE> </CODE><CODE>"returns a value of type 'a"</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val f : unit -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The types of the polymorphic variant constructor are themselves likely to
be polymorphic. 


<PRE><BR># <B>let</B><CODE> </CODE>id<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>`</CODE>Ctor<CODE> </CODE>-&gt;<CODE> </CODE><CODE>`</CODE>Ctor<CODE> </CODE>;;<BR><CODE>val id : [&lt; `Ctor] -&gt; [&gt; `Ctor] = &lt;fun&gt;</CODE><BR>

</PRE>

The type of the value returned from <TT>id</TT> is ``the group of
constructors that contains at least <TT>`Ctor</TT>'' therefore it is
a polymorphic type which can instantiate to a more precise type. In
the same way, the argument of <TT>id</TT> is ``the group of
constructors that contains no more than <TT>`Ctor</TT>'' which is
also likely to be specified. Consequently, they follow the general
polymorphic type mechanism of Objective CAML knowing that they are likely to
be weakened.


<PRE><BR># <B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE>id<CODE> </CODE><CODE>`</CODE>Ctor<CODE> </CODE>;;<BR><CODE>val v : _[&gt; `Ctor] = `Ctor</CODE><BR>

</PRE>

<TT>v</TT>, the result of the application is not polymorphic (as
denoted by the character <TT>_</TT> in the name of the type variable).


<PRE><BR># id<CODE> </CODE>v<CODE> </CODE>;;<BR><CODE>- : _[&gt; `Ctor] = `Ctor</CODE><BR>

</PRE>

<TT>v</TT> is monomorphic and its type is a sub-type of ``contains
at least the constructor <TT>`Ctor</TT>''. Applying it with
<TT>id</TT> will force its type to be a sub-type of``contains
no more than the constructor <TT>`Ctor</TT>''. Logically, it must now
have the type ``contains exactly <TT>`Ctor</TT>''. Let us check.


<PRE><BR># v<CODE> </CODE>;;<BR><CODE>- : [ `Ctor] = `Ctor</CODE><BR>

</PRE>
<BR>
<BR>
As with object types, the types of polymorphic variant constructors can
be open.


<PRE><BR># <B>let</B><CODE> </CODE>is_integer<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>`</CODE>Integer<CODE> </CODE><TT>(</TT>n<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><B>true</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE><CODE>_</CODE><CODE> </CODE>-&gt;<CODE> </CODE><B>false</B><CODE> </CODE>;;<BR><CODE>val is_integer : [&gt; `Integer of int] -&gt; bool = &lt;fun&gt;</CODE><BR># is_integer<CODE> </CODE><TT>(</TT><CODE>`</CODE>Integer<CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>;;<CODE> </CODE><BR><CODE>- : bool = true</CODE><BR># is_integer<CODE> </CODE><CODE>`</CODE>Other<CODE> </CODE>;;<CODE> </CODE><BR><CODE>- : bool = false</CODE><BR>

</PRE>

All the constructors are accepted, but the constructor
<TT>`Integer</TT> must have an integer argument.


<PRE><BR># is_integer<CODE> </CODE><TT>(</TT><CODE>`</CODE>Integer<CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>;;<CODE> </CODE><BR><CODE>Toplevel input:</CODE><BR><CODE># </CODE><BR><CODE>  is_integer (`Integer 3.0) ;; </CODE><BR><CODE>              ^^^^^^^^^^^^</CODE><BR><CODE>This expression has type [&gt; `Integer of float] but is here used with type</CODE><BR><CODE>  [&gt; `Integer of int]</CODE><BR>

</PRE>
<BR>
<BR>
As with object types, the type of a constructor can be cyclic.


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>long<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>`</CODE>Rec<CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>(</TT>long<CODE> </CODE>x<TT>)</TT><CODE> </CODE>;;<BR><CODE>val long : ([&lt; `Rec of 'a] as 'a) -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Finally, let us note that the type can be at the same time a sub-group
and one of a group of constructors. Starting with a a simple example:


<PRE><BR># <B>let</B><CODE> </CODE>ex1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>`</CODE>C1<CODE> </CODE>-&gt;<CODE> </CODE><CODE>`</CODE>C2<CODE> </CODE>;;<CODE> </CODE><BR><CODE>val ex1 : [&lt; `C1] -&gt; [&gt; `C2] = &lt;fun&gt;</CODE><BR>

</PRE>

Now we identify the input and output types of the example by a second
pattern.


<PRE><BR># <B>let</B><CODE> </CODE>ex2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE><CODE>`</CODE>C1<CODE> </CODE>-&gt;<CODE> </CODE><CODE>`</CODE>C2<CODE> </CODE><CODE>|</CODE><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val ex2 : ([&gt; `C2 | `C1] as 'a) -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>

We thus obtain the open type which contains at least <TT>`C2</TT>
since the return type contains at least <TT>`C2</TT>.


<PRE><BR># ex2<CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>`</CODE>C1<CODE> </CODE><CODE>:</CODE><CODE> </CODE><CODE>[&gt;</CODE><CODE> </CODE><CODE>`</CODE>C1<CODE> </CODE><CODE>]</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE>(* is a subtype of [&lt;`C2|`C1| .. &gt;`C2] *)</CODE><BR><CODE>- : _[&gt; `C2 | `C1] = `C2</CODE><BR># ex2<CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>`</CODE>C1<CODE> </CODE><CODE>:</CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>`</CODE>C1<CODE> </CODE><CODE>]</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* is not a subtype of [&lt;`C2|`C1| .. &gt;`C2] *)</CODE><BR><CODE>Toplevel input:</CODE><BR><CODE># ex2 ( `C1 : [ `C1 ] ) ;;   (* is not a subtype of [&lt;`C2|`C1| .. &gt;`C2] *)</CODE><BR><CODE>        ^^^</CODE><BR><CODE>This expression has type [ `C1] but is here used with type [&gt; `C2 | `C1]</CODE><BR>

</PRE>
<BR>
<BR>
<HR>
<A HREF="book-ora210.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora212.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
